home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Plus 1997 #1
/
Amiga Plus CD - 1997 - No. 01.iso
/
pd
/
programmierung
/
oberonv4
/
demos
/
uudecoder.mod
(
.txt
)
< prev
next >
Wrap
Oberon Text
|
1995-12-26
|
4KB
|
174 lines
Syntax10.Scn.Fnt
MODULE UUDecoder; (* ejz, 5.7.95 *)
IMPORT Files, Texts, Oberon;
encTable: ARRAY 64 OF CHAR;
decTable: ARRAY 97 OF INTEGER;
W: Texts.Writer;
PROCEDURE GetName*(T: Texts.Text; VAR beg: LONGINT; VAR name: ARRAY OF CHAR): BOOLEAN;
VAR S: Texts.Scanner;
BEGIN
Texts.OpenScanner(S, T, beg);
Texts.Scan(S);
WHILE ~S.eot & ((S.class # Texts.Name) OR (S.s # "begin")) DO
Texts.Scan(S)
END;
IF (S.class = Texts.Name) & (S.s = "begin") THEN
Texts.Scan(S);
IF S.class # Texts.Name THEN
Texts.Scan(S)
END;
IF S.class = Texts.Name THEN
beg := Texts.Pos(S);
COPY(S.s, name);
RETURN TRUE
END
END;
RETURN FALSE
END GetName;
PROCEDURE DecodeText*(T: Texts.Text; beg: LONGINT; F: Files.File): BOOLEAN;
VAR
R: Texts.Reader;
ch: CHAR;
bytes, chars, c0, c1, c2, c3: INTEGER;
Ri: Files.Rider;
ok: BOOLEAN;
BEGIN
Files.Set(Ri, F, 0);
ok := TRUE;
Texts.OpenReader(R, T, beg);
Texts.Read(R, ch);
REPEAT
WHILE ~R.eot & (ch <= " ") DO
Texts.Read(R, ch)
END;
IF (ch >= CHR(32)) & (ch <= CHR(96)) THEN
bytes := decTable[ORD(ch)];
chars := bytes DIV 3;
IF (bytes MOD 3) # 0 THEN
INC(chars)
END;
Texts.Read(R, ch);
WHILE ~R.eot & (chars > 0) & ok DO
IF (ch >= CHR(32)) & (ch <= CHR(96)) THEN
c0 := decTable[ORD(ch)]
ELSE
ok := FALSE
END;
Texts.Read(R, ch);
IF (ch >= CHR(32)) & (ch <= CHR(96)) THEN
c1 := decTable[ORD(ch)]
ELSE
ok := FALSE
END;
Texts.Read(R, ch);
IF (ch >= CHR(32)) & (ch <= CHR(96)) THEN
c2 := decTable[ORD(ch)]
ELSE
ok := FALSE
END;
Texts.Read(R, ch);
IF (ch >= CHR(32)) & (ch <= CHR(96)) THEN
c3 := decTable[ORD(ch)]
ELSE
ok := FALSE
END;
Files.Write(Ri, CHR(ASH(c0, 2)+ASH(c1, -4)));
DEC(bytes);
IF bytes > 0 THEN
Files.Write(Ri, CHR(ASH(c1, 4)+ASH(c2, -2)));
DEC(bytes);
IF bytes > 0 THEN
Files.Write(Ri, CHR(ASH(c2, 6)+c3));
DEC(bytes)
END
END;
DEC(chars);
Texts.Read(R, ch)
END;
ok := chars <= 0
ELSE
RETURN ch = "e"
END;
UNTIL R.eot OR ~ok;
RETURN ok
END DecodeText;
PROCEDURE Do(T: Texts.Text; beg: LONGINT);
VAR
name: ARRAY 32 OF CHAR;
F: Files.File;
BEGIN
IF GetName(T, beg, name) THEN
Texts.WriteString(W, name);
Texts.WriteString(W, " decoding ");
Texts.Append(Oberon.Log, W.buf);
F := Files.New(name);
IF DecodeText(T, beg, F) THEN
Files.Register(F);
Texts.WriteString(W, "done")
ELSE
Texts.WriteString(W, "failed")
END
ELSE
Texts.WriteString(W, "begin not found")
END;
Texts.WriteLn(W);
Texts.Append(Oberon.Log, W.buf)
END Do;
PROCEDURE Decode*;
VAR
S: Texts.Scanner;
T: Texts.Text;
beg, end, time: LONGINT;
BEGIN
Texts.OpenScanner(S, Oberon.Par.text, Oberon.Par.pos);
Texts.Scan(S);
IF (S.class = Texts.Char) & (S.c ="@") THEN
T := NIL;
time := -1;
Oberon.GetSelection(T, beg, end, time);
IF T # NIL THEN
Do(T, beg)
END
ELSIF (S.class = Texts.Name) & (S.s = "begin") THEN
Do(Oberon.Par.text, Oberon.Par.pos)
ELSE
NEW(T);
WHILE S.class IN {Texts.Name, Texts.String} DO
Texts.Open(T, S.s);
Do(T, 0);
Texts.Scan(S)
END;
IF (S.class = Texts.Char) & (S.c ="^") THEN
T := NIL;
time := -1;
Oberon.GetSelection(T, beg, end, time);
IF T # NIL THEN
Texts.OpenScanner(S, T, beg);
WHILE S.class IN {Texts.Name, Texts.String} DO
Texts.Open(T, S.s);
Do(T, 0);
Texts.Scan(S)
END
END
END
END
END Decode;
PROCEDURE InitUUTables();
VAR i: INTEGER;
BEGIN
FOR i := 0 TO 63 DO
encTable[i] := CHR(i+32)
END;
encTable[0] := CHR(96);
FOR i := 0 TO 96 DO
decTable[i] := 0
END;
FOR i := 0 TO 63 DO
decTable[ORD(encTable[i])] := i
END
END InitUUTables;
BEGIN
Texts.OpenWriter(W);
InitUUTables()
END UUDecoder.